package td.pt.widget;

import java.util.ArrayList;

import td.client.ClientState;
import td.client.ui.Button;
import td.domain.Category;
import td.domain.DemoStore;
import td.domain.Hierarchy;
import td.domain.Topic;
import td.domain.util.StatisticalComparison;
import td.pt.event.CreateTopicEvent;
import td.pt.event.EditEvent;
import td.pt.event.HideAllPopupsEvent;
import td.pt.event.HideAllPopupsEvent.HideAllPopupsHandler;
import td.pt.event.ThoughtListingEvent;
import td.pt.event.UseTopicNavigationEvent;
import td.pt.event.UseTopicNavigationEvent.UseTopicNavigationHandler;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.CellList;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.mvp.client.PopupView;
import com.gwtplatform.mvp.client.PresenterWidget;
import com.gwtplatform.mvp.client.proxy.RevealRootPopupContentEvent;

public class TopicListingPopupPresenter extends
		PresenterWidget<TopicListingPopupPresenter.MyView> implements
		UseTopicNavigationHandler, HideAllPopupsHandler {

	public enum TopicNavigationType {
		SELECT_THOUGHTS_IN_TOPIC, ADD_THOUGHT_TO_TOPIC;
	}

	public interface MyView extends PopupView {
		Button getSelectTopic();

		Button getAddToSelectedTopic();

		Button getAddToNewTopic();

		Button getCancel();

		CellList<Topic> getTopicList();

		SingleSelectionModel<Topic> getSelectionModel();

		Label getBrowserPurposeDescription();

		public RadioButton getOrderAlphabetic();

		public RadioButton getOrderNumberOfThoughts();

		public RadioButton getOrderNumberOfReads();

		public void refresh();
	}

	@Inject
	ClientState state;

	Hierarchy<?> parentHierarchy;

	@Inject
	public TopicListingPopupPresenter(final EventBus eventBus, final MyView view) {
		super(eventBus, view);
	}

	@Override
	protected void onBind() {
		super.onBind();
		registerHandler(getEventBus().addHandler(UseTopicNavigationEvent.getType(),
				this));
		registerHandler(getEventBus().addHandler(HideAllPopupsEvent.getType(),
				this));
		getView().getSelectionModel().addSelectionChangeHandler(
				new SelectionChangeEvent.Handler() {
					public void onSelectionChange(SelectionChangeEvent event) {
						Topic selected = getView().getSelectionModel()
								.getSelectedObject();
						if (selected != null) {
							getView().getSelectTopic().setEnabled(true);
							getView().getAddToSelectedTopic().setEnabled(true);
						} else {
							getView().getSelectTopic().setEnabled(false);
							getView().getAddToSelectedTopic().setEnabled(false);
						}
					}
				});
		getView().getSelectTopic().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				Topic topic = getView().getSelectionModel().getSelectedObject();
				if (topic == null) {
					return;
				}
				ThoughtListingEvent<Topic> topicListingEvent = new ThoughtListingEvent<Topic>(
						"Top Thoughts for the " + topic.getName() + " topic",
						topic);
				getEventBus().fireEvent(topicListingEvent);
				getView().hide();
			}
		});
		getView().getAddToSelectedTopic().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				Topic topic = getView().getSelectionModel().getSelectedObject();
				if (topic == null) {
					return;
				}
				state.getThinker().getDraft().setTopic(topic);
				EditEvent editEvent = new EditEvent(topic);
				getEventBus().fireEvent(editEvent);
				getView().hide();
			}
		});
		getView().getAddToNewTopic().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				Topic topic = getView().getSelectionModel().getSelectedObject();
				if (topic != null) {
					return;
				}
				CreateTopicEvent createTopicEvent = new CreateTopicEvent(
						TopicListingPopupPresenter.this,
						(Category) parentHierarchy);
				getEventBus().fireEvent(createTopicEvent);
			}
		});
		getView().getCancel().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				getView().hide();
			}
		});

		getView().getOrderAlphabetic().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				refresh(StatisticalComparison.ALPHABETIC);
			}
		});
		getView().getOrderNumberOfReads().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				refresh(StatisticalComparison.NUMBER_OF_THOUGHT_READS);
			}
		});
		getView().getOrderNumberOfThoughts().addClickHandler(
				new ClickHandler() {
					@Override
					public void onClick(ClickEvent event) {
						refresh(StatisticalComparison.NUMBER_OF_THOUGHTS);
					}
				});
	}

	private void refresh(StatisticalComparison comparisonType) {
		Topic.currentComparisonType = comparisonType;

		ArrayList<Topic> topics = parentHierarchy.getTopics();
		DemoStore.db().reorder(topics);
		getView().getTopicList().setRowCount(topics.size(), true);
		getView().getTopicList().setRowData(topics);
		getView().refresh();
	}

	@Override
	protected void onReveal() {
		super.onReveal();
	}

	/* (non-Javadoc)
	 * @see td.pt.event.UseTopicNavigationEvent.UseTopicNavigationHandler#onUseTopicNavigation(td.pt.event.UseTopicNavigationEvent)
	 */
	@Override
	public void onUseTopicNavigation(UseTopicNavigationEvent event) {

		StringBuilder subHeaderText = new StringBuilder();
		parentHierarchy = event.getParentHierarchy();
		if (parentHierarchy instanceof Category) {
			subHeaderText.append("Category '");
		} else {
			subHeaderText.append("Tag '");
		}
		subHeaderText.append(parentHierarchy.getName());
		subHeaderText.append("': ");
		switch (event.getNavigationType()) {
		case ADD_THOUGHT_TO_TOPIC:
			subHeaderText.append("Select a Topic for new Thought");
			getView().getAddToSelectedTopic().setVisible(true);
			getView().getAddToNewTopic().setVisible(true);
			getView().getSelectTopic().setVisible(false);
			break;
		case SELECT_THOUGHTS_IN_TOPIC:
			subHeaderText.append("Select a Topic to display Thoughts");
			getView().getAddToSelectedTopic().setVisible(false);
			getView().getAddToNewTopic().setVisible(false);
			getView().getSelectTopic().setVisible(true);
			break;
		}
		getView().getAddToSelectedTopic().setEnabled(false);
		getView().getSelectTopic().setEnabled(false);
		getView().getAddToNewTopic().setEnabled(true);

		getView().getBrowserPurposeDescription().setText(
				subHeaderText.toString());
		getView().getTopicList().setRowCount(
				parentHierarchy.getTopics().size(), true);
		getView().getTopicList().setRowData(parentHierarchy.getTopics());
		RevealRootPopupContentEvent.fire(event.getSource(),
				TopicListingPopupPresenter.this);
	}

	/* (non-Javadoc)
	 * @see td.pt.event.HideAllPopupsEvent.HideAllPopupsHandler#onHideAllPopups(td.pt.event.HideAllPopupsEvent)
	 */
	@Override
	public void onHideAllPopups(HideAllPopupsEvent event) {
		TopicListingPopupPresenter.this.getView().hide();
	}
}
